一道有意思的题
以下我的学习分析心路历程,以及我自己又多加了几道菜;希望对你有帮助
先上菜
new Promise((resolve, reject) => {
console.log('promise1');
resolve();
}).then(() => {
console.log('then11');
new Promise((resolve, reject) => {
console.log('promise2');
resolve();
}).then(() => {
console.log('then21');
}).then(() => {
console.log('then23');
});
}).then(() => {
console.log('then12');
});
分析第一道菜
- 第一次看到我做错了,答案是
promise1
then11
promise2
then21
then12
then23
- 我的疑惑就是
then12
为什么在then21
和then23
之间,很奇怪。说明什么呢?我对Promise
的内部实现还不了解,那只能去看源码了。在学习过程中,自己也尝试改变了几处,也贴上来吧,大家看看
看完后我的理解
先分析下面代码
new Promise((resolve, reject) => {
console.log('promise1');
resolve();
})
- 第一步
console.log('promise1')
,这是第一个promise
实例 - 第二步
resolve()
,他是一个异步,放入异步队列中,取名异步1 - 第三步
this.status
状态是pending
接着执行下面代码
.then(() => {
console.log('then11');
new Promise((resolve, reject) => {
console.log('promise2');
resolve();
}).then(() => {
console.log('then21');
}).then(() => {
console.log('then23');
});
})
- 因为状态是
pending
,将then方法回调函数加入执行队列(一个数组)等待执行(专用来放then方法的数组),该then
方法取名方法1
重点接着执行什么?
并不是执行.then(() => {console.log(then12)})
,要记住的是then
的参数方法执行时机是当前(属于自己的)promise状态改变才会执行,谁改变resolve或者rejectd的执行
,那么这里then的promise哪里来,就是上面的方法1
中来看他的return值
所以开始执行异步1(我都有取名的,看👆),第一个
promise实例
状态变为FULFILLED
- 首先
resolve()
参数为undefind
不是一个promise类型,所以执行
执行队列(一个数组),即方法1,也就是第一个
then`的参数 - 因为状态改变所以开始执行方法1
() => {
console.log('then11');
new Promise((resolve, reject) => {
console.log('promise2');
resolve(); //新的resolve 取名异步2
}).then(() => {
console.log('then21');
}).then(() => {
console.log('then23');
});
}
- 第一步打印
console.log('then11');
- 又新建了一个
Promise
,打印console.log('promise2');
-
resolve();
又一个异步,放入异步队列中,取名异步2 - 然后因为新的
promise
它的状态是pengding
,所以() => {console.log('then21');}
方法放入新的promise的执行队列的数组中(和上面一样专用来放then方法的数组) - 同理后面的
then
并不回执行,它需要等待新的resolve的执行
,来改变状态执行then
重点2
-
因为方法1的没有return,即return 一个undefined
,但我们都知道then
会默认返回一个return new Promise((resolve, reject) => {})
对象,所以这时候他是执行了的一个异步操作resolve()
取名异步3, - 所以有了这个异步3,这个
return
的promise
的状态为pending
,所以then(() => {console.log(then12)})
加入到(专用来放then方法的数组)的执行回调数组中
然后开始执行异步队列的函数,有两个异步2和异步3,先执行异步2,接下来的操作和重点2
是一样的又会return new Promise((resolve, reject) => {})
,又会有一个异步4resolve()
,接着讲then
方法放入数组中,等待resolve()
改变promise
状态来执行then
方法
- 所以在等待期间会执行
异步3
,然后打印console.log(then12)
- 最后打印
console.log(then23)
总结要点
-
then(func)
执行时机是等待一个与它相关的promise
的状态改变 -
then(func)
中的func
默认会return new Promise((resolve, reject) => {resolve()})
用于下一个then(func)
- 如果我们手动
return 一个promise
结果就会不同,看下面例子
再变个花样
new Promise((resolve, reject) => {
console.log('promise1');
resolve(); //异步1
}).then(() => {
console.log('then11');
return new Promise((resolve, reject) => {
console.log('promise2');
resolve(); //异步2
}).then(() => {
console.log('then21');
//默认resolve() 异步3
}).then(() => {
console.log('then23');
//默认resolve() 异步4
});
}).then(() => {
console.log('then12');
});
分析
- 看到一个
then(func)
中我们直接返回了一个promise
,所以先加入第一异步2,并且要等待它相关的promise状态改变,但是它状态改变了,那就是等异步2的执行,一旦执行,接着就是() =>{console.log('then23'); //默认resolve() 异步4}
的执行了,所以异步4先一步比异步5加入,也就先执行了, - 所以结果就是
promise1
then11
promise2
then21
then23
then12
我再来变个样
new Promise((resolve, reject) => {
console.log('promise1');
resolve(); //异步1
}).then(() => {
console.log('then11');
new Promise((resolve, reject) => {
console.log('promise2');
resolve(); //异步2
}).then(() => {
console.log('then21');
//异步3
}).then(() => {
console.log('then23');
//异步4
});
return Promise.resolve(1) //异步5
}).then(() => {
console.log('then12');
});
分析一下这几个异步就要能知道答案了
console.log('promise1');
- 先加入异步1, 执行后输出
console.log('then11');
console.log('promise2');
- 在加入异步2, 再加入异步5
- 先执行异步2,
console.log('then21');
并将加入异步4 - 再执行异步5, 但这个异步和下面的
then
不相关,因为这边隐藏的会再下加入一个resolve()(即异步6) - 接着先执行异步4, 输出
console.log('then23');
- 接着先执行异步6, 输出
console.log('then12');
**粗体** _斜体_ [链接](http://example.com) `代码` - 列表 > 引用
。你还可以使用@
来通知其他用户。